/**
 ** 保留站的实现逻辑
 ** 标记一下，这里应该准备三个就绪队列，分别对应alu，乘法和除法
 ** 每次时钟上升沿，从队列中取出一个就绪块，送入到执行单元，运算得到结果
**/

module saveStation (
    input wire clk,
    input wire save_en_1,                  //保存到保留站的使能信号
    input wire save_en_2,
    input wire [11:0] pc_1, pc_2,
    input wire [2:0] work_mode_1,           //运算模式--普通整数运算 or 整数乘除法 or 浮点
    input wire [2:0] work_mode_2,
    input wire [3:0] alu_ctrl_1,           //运算器的控制信号
    input wire [3:0] alu_ctrl_2,
    input wire [3:0] complex_ctrl_1,       //乘除法的控制信号
    input wire [3:0] complex_ctrl_2,    
    input wire [31:0] imm_1, imm_2,        //立即数的输入  
    input wire rs_1_ready,                 //寄存器是否准备就绪的标记
    input wire rt_1_ready,             
    input wire rs_2_ready,             
    input wire rt_2_ready,             
    input wire [4:0] rs_1_relation,    //和rs寄存器关联的ROB号
    input wire [4:0] rt_1_relation,    //和rt寄存器关联的ROB号
    input wire [4:0] rd_1_relation,    //和rd寄存器关联的ROB号
    input wire [4:0] rs_2_relation,    //和rs寄存器关联的ROB号
    input wire [4:0] rt_2_relation,    //和rt寄存器关联的ROB号
    input wire [4:0] rd_2_relation,    //和rd寄存器关联的ROB号
    input wire [31:0] rs_1_value,      //寄存器的值
    input wire [31:0] rt_1_value,      
    input wire [31:0] rs_2_value,      //寄存器的值
    input wire [31:0] rt_2_value,
    input wire [2:0] dm_rd_ctrl_1, dm_rd_ctrl_2,  //RAM读取控制信号
    input wire [1:0] dm_wr_ctrl_1, dm_wr_ctrl_2,  //RAM写入控制信号
    input wire alu_commit_en, mul_commit_en, div_commit_en, specific_commit_en, mem_commit_en,
    input wire [4:0] alu_commit_save_no, mul_commit_save_no, div_commit_save_no, specific_commit_save_no, mem_commit_save_no,
    input wire [4:0] alu_commit_rob_no, mul_commit_rob_no, div_commit_rob_no, mem_commit_rob_no, 
    input wire [31:0] alu_commit_value, mul_commit_value, div_commit_value, specific_commit_value, mem_commit_value,
    output reg [3:0] common_ctrl,      
    output reg [31:0] alu_X, alu_Y,
    output reg alu_ready_en, div_ready_en, mul_ready_en, specific_ready_en,
    output reg [4:0] alu_rd_rob_no, mul_rd_rob_no, div_rd_rob_no, 
    output reg [4:0] alu_save_no, mul_save_no, div_save_no, specific_save_no,
    output reg [3:0] mul_ctrl,
    output reg [31:0] mul_X, mul_Y,
    output reg [3:0] div_ctrl,
    output reg [31:0] div_X, div_Y,
    output reg [3:0] specific_ctrl,
    output reg [31:0] specific_X, specific_Y,
    output reg read_en_mem, write_en_mem,              //RAM读写使能信号
    output reg [2:0] dm_rd_ctrl_mem,
    output reg [1:0] dm_wr_ctrl_mem,
    output reg [31:0] dm_addr_mem, dm_din_mem,
    output reg [4:0] save_no_mem, 
    output reg [4:0] rd_rob_no_mem
);
    //保留站的一些数组，用来存储在此地等待的指令的信息
    reg [31:0] rs_ok, rt_ok;                                   //寄存器是否准备好的标记位
    reg [31:0] rs_value[0:31], rt_value[0:31], imm[0:31];      //寄存器对应的值
    reg [4:0] rs_relation[0:31], rt_relation[0:31], rd_relation[0:31];  
    reg [11:0] pc[0:31];
    reg [3:0] alu_ctrl[0:31];                                  //运算器的控制信号
    reg [2:0] work_mode[0:31];                                 //运算模式，用来选择运算器
    reg [1:0] dm_write_ctrl[0:31];                             //RAM的控制信号，用来实现数据的存取
    reg [2:0] dm_read_ctrl[0:31];
    reg [31:0] specific_value [0:31];                          //非算数指令运算部分的运算结果
    reg [31:0] specific_ok;                                    //非算数指令运算部分结果就绪位


    //定义空闲队列，方便查找到空闲可用的保留站条目
    reg [4:0] freeQueue[0:31];
    reg [4:0] free_tail;
    reg [4:0] free_head;
    reg [4:0] free_temp_index;

    //专用运算器的操作数和控制信号
    reg [31:0] specific_ok_x [0:15];
    reg [31:0] specific_ok_y [0:15];
    reg [3:0] specific_ok_ctrl [0:15];

    //各种就绪队列需要用到的一些信号
    reg common_alu_push_en_1, common_alu_push_en_2, common_alu_push_en_3, common_alu_push_en_4;
    reg [4:0] common_alu_push_value_1, common_alu_push_value_2, common_alu_push_value_3, common_alu_push_value_4;
    wire common_alu_pop_ready;
    wire [4:0] common_alu_pop_value;

    reg mul_alu_push_en_1, mul_alu_push_en_2, mul_alu_push_en_3, mul_alu_push_en_4;
    reg [4:0] mul_alu_push_value_1, mul_alu_push_value_2, mul_alu_push_value_3, mul_alu_push_value_4;
    wire mul_alu_pop_ready;
    wire [4:0] mul_alu_pop_value;

    reg div_alu_push_en_1, div_alu_push_en_2, div_alu_push_en_3, div_alu_push_en_4;
    reg [4:0] div_alu_push_value_1, div_alu_push_value_2, div_alu_push_value_3, div_alu_push_value_4;
    wire div_alu_pop_ready;
    wire [4:0] div_alu_pop_value;

    reg specific_alu_push_en_1, specific_alu_push_en_2, specific_alu_push_en_3, specific_alu_push_en_4;
    reg [4:0] specific_alu_push_value_1, specific_alu_push_value_2, specific_alu_push_value_3, specific_alu_push_value_4;
    wire specific_alu_pop_ready;
    wire [4:0] specific_alu_pop_value;

    reg mem_alu_push_en_1, mem_alu_push_en_2, mem_alu_push_en_3, mem_alu_push_en_4;
    reg [4:0] mem_alu_push_value_1, mem_alu_push_value_2, mem_alu_push_value_3, mem_alu_push_value_4;
    wire mem_alu_pop_ready;
    wire [4:0] mem_alu_pop_value;

    //标记哪几个保留站想要进入就绪队列
    reg [31:0] save_ok_palette;

    //遍历需要的指针
    integer i, j, k;
    

    initial begin
        free_temp_index <= 0;
        //初始化空闲队列指针
        free_head <= 0;
        free_tail <= 31;  //初始情况下，所有的保留站条目都是可用的，即队列是满的
        //初始化调色盘
        save_ok_palette <= 32'h00000000;
        //初始化保留站和队列
        for (i=0; i<32; i=i+1) begin
            rs_ok[i] <= 0; 
            rs_ok[i] <= 0;
            specific_ok[i] <= 0;
            freeQueue[i] <= i;
        end
    end

    initial begin
        //初始化消息队列的控制信号
        common_alu_push_en_1 <= 0;
        common_alu_push_en_2 <= 0;
        common_alu_push_en_3 <= 0;
        common_alu_push_en_4 <= 0;
        mul_alu_push_en_1 <= 0;
        mul_alu_push_en_2 <= 0;
        mul_alu_push_en_3 <= 0;
        mul_alu_push_en_4 <= 0;
        div_alu_push_en_1 <= 0;
        div_alu_push_en_2 <= 0;
        div_alu_push_en_3 <= 0;
        div_alu_push_en_4 <= 0;
        specific_alu_push_en_1 <= 0;
        specific_alu_push_en_2 <= 0;
        specific_alu_push_en_3 <= 0;
        specific_alu_push_en_4 <= 0;
        mem_alu_push_en_1 <= 0;
        mem_alu_push_en_2 <= 0;
        mem_alu_push_en_3 <= 0;
        mem_alu_push_en_4 <= 0;
    end

    //第一阶段分配的保留站的条目块号
    reg [4:0] save_no_1_stage1, save_no_2_stage1;
    reg save_en_1_stage1, save_en_2_stage1;
    reg [2:0] dm_rd_ctrl_1_stage1, dm_rd_ctrl_2_stage1;  
    reg [1:0] dm_wr_ctrl_1_stage1, dm_wr_ctrl_2_stage1;
    //第一阶段需要向后传递的信号
    reg [11:0] pc_1_stage1, pc_2_stage1;
    reg [2:0] work_mode_1_stage1, work_mode_2_stage1;
    reg [31:0] imm_1_stage1, imm_2_stage1;
    reg [3:0] alu_ctrl_1_stage1, alu_ctrl_2_stage1;
    reg [3:0] complex_ctrl_1_stage1, complex_ctrl_2_stage1;
    reg rs_1_ready_stage1, rt_1_ready_stage1;
    reg rs_2_ready_stage1, rt_2_ready_stage1;
    reg [4:0] rs_1_relation_stage1, rt_1_relation_stage1, rd_1_relation_stage1; 
    reg [4:0] rs_2_relation_stage1, rt_2_relation_stage1, rd_2_relation_stage1;
    reg [31:0] rs_1_value_stage1, rt_1_value_stage1, rs_2_value_stage1, rt_2_value_stage1;

    always @(posedge clk) begin
        //分配空闲保留站块
        if (save_en_1==1 && save_en_2==1) begin
            save_no_1_stage1 <= freeQueue[free_head];
            save_no_2_stage1 <= freeQueue[(free_head+1)%32];
            //指针后移
            free_head <= (free_head+2)%32;
            save_en_1_stage1 <= 1;
            save_en_2_stage1 <= 1;
            if (rs_1_ready && rt_1_ready) begin
                //第一条指令可以加入就绪队列
                save_ok_palette[freeQueue[free_head]] <= 1;
            end
            else begin
                save_ok_palette[freeQueue[free_head]] <= 0;
            end

            if (rs_2_ready && rt_2_ready) begin
                //第二条指令可以加入就绪队列
                save_ok_palette[freeQueue[(free_head+1)%32]] <= 1;
            end
            else begin
                save_ok_palette[freeQueue[(free_head+1)%32]] <= 0;
            end
        end
        else if (save_en_1==1) begin
            save_no_1_stage1 <= freeQueue[free_head];
            //指针后移
            free_head <= (free_head+1)%32;
            save_en_1_stage1 <= 1;
            save_en_2_stage1 <= 0;

            if (rs_1_ready && rt_1_ready) begin
                //第一条指令可以加入就绪队列
                save_ok_palette[freeQueue[free_head]] <= 1;
            end
            else begin
                save_ok_palette[freeQueue[free_head]] <= 0;
            end
        end
        else if (save_en_2==1) begin
            save_no_2_stage1 <= freeQueue[free_head];
            //指针后移
            free_head <= (free_head+1)%32;
            save_en_1_stage1 <= 0;
            save_en_2_stage1 <= 1;

            if (rs_2_ready && rt_2_ready) begin
                //第二条指令可以加入就绪队列
                save_ok_palette[freeQueue[free_head]] <= 1;
            end
            else begin
                save_ok_palette[freeQueue[free_head]] <= 0;
            end
        end
        else begin
            save_en_1_stage1 <= 0;
            save_en_2_stage1 <= 0;
        end

        //将现在没用到的信号传递到下一级
        pc_1_stage1 <= pc_1;
        pc_2_stage1 <= pc_2;
        work_mode_1_stage1 <= work_mode_1;
        work_mode_2_stage1 <= work_mode_2;
        imm_1_stage1 <= imm_1;
        imm_2_stage1 <= imm_2;
        dm_rd_ctrl_1_stage1 <= dm_rd_ctrl_1;
        dm_rd_ctrl_2_stage1 <= dm_rd_ctrl_2;
        dm_wr_ctrl_1_stage1 <= dm_wr_ctrl_1;
        dm_wr_ctrl_2_stage1 <= dm_wr_ctrl_2;
        alu_ctrl_1_stage1 <= alu_ctrl_1; 
        alu_ctrl_2_stage1 <= alu_ctrl_2;
        complex_ctrl_1_stage1 <= complex_ctrl_1;
        complex_ctrl_2_stage1 <= complex_ctrl_2;      
        rs_1_ready_stage1 <= rs_1_ready;
        rt_1_ready_stage1 <= rt_1_ready;     
        rs_2_ready_stage1 <= rs_2_ready;     
        rt_2_ready_stage1 <= rt_2_ready;     
        rs_1_relation_stage1 <= rs_1_relation; 
        rt_1_relation_stage1 <= rt_1_relation; 
        rd_1_relation_stage1 <= rd_1_relation; 
        rs_2_relation_stage1 <= rs_2_relation;
        rt_2_relation_stage1 <= rt_2_relation;
        rd_2_relation_stage1 <= rd_2_relation;
        rs_1_value_stage1 <= rs_1_value;
        rt_1_value_stage1 <= rt_1_value;      
        rs_2_value_stage1 <= rs_2_value;
        rt_2_value_stage1 <= rt_2_value; 
    end

    //现在这里还是会出现同时更改就绪队列指针的情况，需要调整结构避免这种竞争状态的发生
    always @(posedge clk) begin
        if (save_en_1_stage1==1) begin
            //将数据写入到保留站备用
            rs_value[save_no_1_stage1] <= rs_1_value_stage1;
            rt_value[save_no_1_stage1] <= rt_1_value_stage1;
            rd_relation[save_no_1_stage1] <= rd_1_relation_stage1;
            work_mode[save_no_1_stage1] <= work_mode_1_stage1;
            work_mode[save_no_1_stage1] <= work_mode_1_stage1;
            pc[save_no_1_stage1] <= pc_1_stage1;
            imm[save_no_1_stage1] <= imm_1_stage1;
            if (work_mode_1_stage1 == 3'b000 || work_mode_1_stage1 == 3'b011 || work_mode_1_stage1 == 3'b110) begin   //普通alu运算
                alu_ctrl[save_no_1_stage1] <= alu_ctrl_1_stage1;
            end
            else if (work_mode_1_stage1 == 3'b001 || work_mode_1_stage1 == 3'b010) begin  //乘除法
                alu_ctrl[save_no_1_stage1] <= complex_ctrl_1_stage1;  
            end
            else if (work_mode_1_stage1 == 3'b100 || work_mode_1_stage1 == 3'b101) begin  //访存指令
                dm_write_ctrl[save_no_1_stage1] = dm_wr_ctrl_1_stage1;
                dm_read_ctrl[save_no_1_stage1] = dm_rd_ctrl_1_stage1;
                alu_ctrl[save_no_1_stage1] = 4'b0000;
            end
            else begin
                alu_ctrl[save_no_1_stage1] <= alu_ctrl_1_stage1;
            end
           

            if (rs_1_ready_stage1==1) begin 
                //操作数rs，已经准备好
                rs_ok[save_no_1_stage1] <= 1;
            end
            else begin
                rs_ok[save_no_1_stage1] <= 0;
                rs_relation[save_no_1_stage1] <= rs_1_relation_stage1;
            end

            if (rt_1_ready_stage1==1) begin
                //操作数rt，已经准备好
                rt_ok[save_no_1_stage1] <= 1;
            end
            else begin
                rt_ok[save_no_1_stage1] <= 0;
                rt_relation[save_no_1_stage1] <= rt_1_relation_stage1;
            end
        end

        if (save_en_2_stage1==1) begin
            //处理第二条指令
            //将数据写入到保留站备用
            rs_value[save_no_2_stage1] <= rs_2_value_stage1;
            rt_value[save_no_2_stage1] <= rt_2_value_stage1;
            rd_relation[save_no_2_stage1] <= rd_2_relation_stage1;
            work_mode[save_no_2_stage1] <= work_mode_2_stage1;
            if (work_mode_2_stage1 == 3'b000) begin   //普通alu运算
                alu_ctrl[save_no_2_stage1] <= alu_ctrl_2_stage1;
            end
            else if (work_mode_2_stage1 == 3'b001 || work_mode_2_stage1 == 3'b010) begin  //乘除法
                alu_ctrl[save_no_2_stage1] <= complex_ctrl_2_stage1;  
            end
            else begin
                alu_ctrl[save_no_2_stage1] <= alu_ctrl_2_stage1;
            end

            if (rs_2_ready_stage1==1) begin
                rs_ok[save_no_2_stage1] <= 1;
            end
            else begin
                rs_ok[save_no_2_stage1] <= 0;
                rs_relation[save_no_2_stage1] <= rs_2_relation_stage1;
            end

            if (rt_2_ready==1) begin
                rt_ok[save_no_2_stage1] <= 1;
            end
            else begin
                rt_ok[save_no_2_stage1] <= 0;
                rt_relation[save_no_2_stage1] <= rt_2_relation_stage1;
            end
        end
    end

    //处理调色盘上的内容
    always @(posedge clk) begin
        for (i=0; i<32; i=i+1) begin
            //如果两个操作都准备好了，就放入就绪队列
            if (save_ok_palette[i]) begin
                //32位内容八个一组，进行分配
                if (save_no_1_stage1>=0 && save_no_1_stage1<=7)  begin
                    if (save_ok_palette[7:0] & ((1<<save_no_1_stage1)-1) == 0) begin
                        //说明调色板上当前位是为1的最低位
                        //根据所运行模式，加入到不同的队列中
                        if (work_mode_1_stage1 == 3'b000) begin  //普通alu运算
                            common_alu_push_en_1 <= 1;
                            common_alu_push_value_1 <= save_no_1_stage1; 
                        end
                        else if (work_mode_1_stage1 == 3'b001) begin  //整数乘法
                            mul_alu_push_en_1 <= 1;
                            mul_alu_push_value_1 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b010) begin  //整数除法
                            div_alu_push_en_1 <= 1;
                            div_alu_push_value_1 <= save_no_1_stage1;
                        end
                        else begin
                            //TODO 后面可能会支持浮点运算之类的
                        end
                    end
                end

                if (save_no_1_stage1>=8 && save_no_1_stage1<=15)  begin
                    if (save_ok_palette[15:8] & ((1<<(save_no_1_stage1-8))-1) == 0) begin
                        //说明调色板上当前位是为1的最低位
                        //根据所运行模式，加入到不同的队列中
                        if (work_mode_1_stage1 == 3'b000) begin  //普通alu运算
                            common_alu_push_en_2 <= 1;
                            common_alu_push_value_2 <= save_no_1_stage1; 
                        end
                        else if (work_mode_1_stage1 == 3'b001) begin  //整数乘法
                            mul_alu_push_en_2 <= 1;
                            mul_alu_push_value_2 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b010) begin  //整数除法
                            div_alu_push_en_2 <= 1;
                            div_alu_push_value_2 <= save_no_1_stage1;
                        end
                        else begin
                            //TODO 后面可能会支持浮点运算之类的
                        end
                    end
                end

                if (save_no_1_stage1>=16 && save_no_1_stage1<=23)  begin
                    if (save_ok_palette[23:16] & ((1<<(save_no_1_stage1-16))-1) == 0) begin
                        //说明调色板上当前位是为1的最低位
                        //根据所运行模式，加入到不同的队列中
                        if (work_mode_1_stage1 == 3'b000) begin  //普通alu运算
                            common_alu_push_en_3 <= 1;
                            common_alu_push_value_3 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b001) begin  //整数乘法
                            mul_alu_push_en_3 <= 1;
                            mul_alu_push_value_3 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b010) begin  //整数除法
                            div_alu_push_en_3 <= 1;
                            div_alu_push_value_3 <= save_no_1_stage1;
                        end
                        else begin
                            //TODO 后面可能会支持浮点运算之类的
                        end
                    end
                end

                if (save_no_1_stage1>=24 && save_no_1_stage1<=31)  begin
                    if (save_ok_palette[31:24] & ((1<<(save_no_1_stage1-24))-1) == 0) begin
                        //说明调色板上当前位是为1的最低位
                        //根据所运行模式，加入到不同的队列中
                        if (work_mode_1_stage1 == 3'b000) begin  //普通alu运算
                            common_alu_push_en_4 <= 1;
                            common_alu_push_value_4 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b001) begin  //整数乘法
                            mul_alu_push_en_4 <= 1;
                            mul_alu_push_value_4 <= save_no_1_stage1;
                        end
                        else if (work_mode_1_stage1 == 3'b010) begin  //整数除法
                            div_alu_push_en_4 <= 1;
                            div_alu_push_value_4 <= save_no_1_stage1;
                        end
                        else begin
                            //TODO 后面可能会支持浮点运算之类的
                        end
                    end
                end
            end
        end
    end

    //每个时钟周期，发射一组运算到乘法运算部件
    always @(posedge clk) begin
        if (common_alu_pop_ready) begin
            mul_ctrl <= alu_ctrl[common_alu_pop_value];
            mul_X <= rs_value[common_alu_pop_value];
            mul_Y <= rt_value[common_alu_pop_value];
            mul_save_no <= common_alu_pop_value;
            mul_rd_rob_no <= rd_relation[common_alu_pop_value];
            mul_ready_en <= 1;
        end
        else begin
            mul_ready_en <= 0;
        end
    end

    //每个时钟周期，发射一组运算到除法运算部件
    always @(posedge clk) begin
        if (div_alu_pop_ready) begin
            div_ctrl <= alu_ctrl[div_alu_pop_value];
            div_X <= rs_value[div_alu_pop_value];
            div_Y <= rt_value[div_alu_pop_value];
            div_save_no <= div_alu_pop_value;
            div_rd_rob_no <= rd_relation[div_alu_pop_value];
            div_ready_en <= 1;
        end
        else begin
            div_ready_en <= 0;
        end
    end

    //每个时钟周期，发射一组运算到普通运算部件
    always @(posedge clk) begin
        if (common_alu_pop_ready) begin
            common_ctrl <= alu_ctrl[common_alu_pop_value];
            alu_X <= rs_value[common_alu_pop_value];
            alu_Y <= rt_value[common_alu_pop_value];
            alu_save_no <= common_alu_pop_value;
            alu_rd_rob_no <= rd_relation[common_alu_pop_value];
            alu_ready_en <= 1;  //使能位，告知运算单元可以开始工作了
        end
        else begin
            alu_ready_en <= 0; 
        end
    end

    //每个时钟周期，发射一组运算到访存部件
    always @(posedge clk) begin
        if (mem_alu_pop_ready) begin
            dm_rd_ctrl_mem <= dm_read_ctrl[mem_alu_pop_value];
            dm_wr_ctrl_mem <= dm_write_ctrl[mem_alu_pop_value];
            dm_addr_mem <= specific_value[mem_alu_pop_value];
            dm_din_mem <= rt_value[mem_alu_pop_value];
            save_no_mem <= mem_alu_pop_value;
            if (work_mode[mem_alu_pop_value]==3'b100) begin
                read_en_mem <= 1;
                write_en_mem <= 0;
            end
            else if (work_mode[mem_alu_pop_value]==3'b101) begin
                read_en_mem <= 0;
                write_en_mem <= 1;
            end
            else begin
                read_en_mem <= 0;
                write_en_mem <= 0;
            end
            rd_rob_no_mem <= rd_relation[mem_alu_pop_value];
        end
    end

    //每个时钟周期，发射一组特殊运算部件
    always @(posedge clk) begin
        if (specific_alu_pop_ready) begin
            specific_X <= specific_ok_x[specific_alu_pop_value];
            specific_Y <= specific_ok_y[specific_alu_pop_value];
            specific_ctrl <= specific_ok_ctrl[specific_alu_pop_value];
            specific_save_no <= specific_alu_pop_value;
            specific_ready_en <= 1;
        end
        else begin
            specific_ready_en <= 0;
        end
    end

    //运算结果的写回逻辑 -- 目前的想法是，以前的那个逻辑在仿真能够通过，但是可能要占据较大的面积
    always @(posedge clk) begin
        for (i=0; i<32; i=i+1) begin
            //如果的保留站条目确实在等待这个结果的写回，更新之
            if (alu_commit_en) begin
                if (rs_relation[i]==alu_commit_rob_no) begin
                    rs_value[i] <= alu_commit_value;
                    rs_ok[i] <= 1;
                end
                
                if (rt_relation[i]==alu_commit_rob_no) begin
                    rt_value[i] <= alu_commit_value;
                    rt_ok[i] <= 1;
                end
            end

            if (mul_commit_en) begin
                if (rs_relation[i]==mul_commit_rob_no) begin
                    rs_value[i] <= mul_commit_value;
                    rs_ok[i] <= 1;
                end
                
                if (rt_relation[i]==mul_commit_rob_no) begin
                    rt_value[i] <= mul_commit_value;
                    rt_ok[i] <= 1;
                end
            end

            if (div_commit_en) begin
                if (rs_relation[i]==div_commit_rob_no) begin
                    rs_value[i] <= div_commit_value;
                    rs_ok[i] <= 1;
                end
                
                if (rt_relation[i]==div_commit_rob_no) begin
                    rt_value[i] <= div_commit_value;
                    rt_ok[i] <= 1;
                end
            end

            //如果寄存器都属于就绪状态，则在调色板上将其标志为1，否则为0
            if (rt_ok[i] && rs_ok[i]) begin
                save_ok_palette[i] <= 1;
            end
            else begin
                save_ok_palette[i] <= 0;
            end
        end
    end

    //实例化一组普通运算就绪队列
    ok_queue common_alu_queue(.clk(clk), .rst(rst), .push_en_1(common_alu_push_en_1), .push_value_1(common_alu_push_value_1), .push_en_2(common_alu_push_en_2), .push_value_2(common_alu_push_value_2), .push_en_3(common_alu_push_en_3), .push_value_3(common_alu_push_value_3), .push_en_4(common_alu_push_en_4), .push_value_4(common_alu_push_value_4), .pop_ready(common_alu_pop_ready), .pop_value(common_alu_pop_value));

    //实例化一组特殊运算就绪队列
    ok_queue specific_alu_queue(.clk(clk), .rst(rst), .push_en_1(specific_alu_push_en_1), .push_value_1(specific_alu_push_value_1), .push_en_2(specific_alu_push_en_2), .push_value_2(specific_alu_push_value_2), .push_en_3(specific_alu_push_en_3), .push_value_3(specific_alu_push_value_3), .push_en_4(specific_alu_push_en_4), .push_value_4(specific_alu_push_value_4), .pop_ready(specific_alu_pop_ready), .pop_value(specific_alu_pop_value));

    //实例化一组乘法运算就绪队列
    ok_queue mul_queue(.clk(clk), .rst(rst), .push_en_1(mul_alu_push_en_1), .push_value_1(mul_alu_push_value_1), .push_en_2(mul_alu_push_en_2), .push_value_2(mul_alu_push_value_2), .push_en_3(mul_alu_push_en_3), .push_value_3(mul_alu_push_value_3), .push_en_4(mul_alu_push_en_4), .push_value_4(mul_alu_push_value_4), .pop_ready(mul_alu_pop_ready), .pop_value(mul_alu_pop_value));

    //实例化一组除法运算就绪队列
    ok_queue div_queue(.clk(clk), .rst(rst), .push_en_1(div_alu_push_en_1), .push_value_1(div_alu_push_value_1), .push_en_2(div_alu_push_en_2), .push_value_2(div_alu_push_value_2), .push_en_3(div_alu_push_en_3), .push_value_3(div_alu_push_value_3), .push_en_4(div_alu_push_en_4), .push_value_4(div_alu_push_value_4), .pop_ready(div_alu_pop_ready), .pop_value(div_alu_pop_value));

    //实例化一组访存操作就绪队列
    ok_queue mem_queue(.clk(clk), .rst(rst), .push_en_1(mem_alu_push_en_1), .push_value_1(mem_alu_push_value_1), .push_en_2(mem_alu_push_en_2), .push_value_2(mem_alu_push_value_2), .push_en_3(mem_alu_push_en_3), .push_value_3(mem_alu_push_value_3), .push_en_4(mem_alu_push_en_4), .push_value_4(mem_alu_push_value_4), .pop_ready(mem_alu_pop_ready), .pop_value(mem_alu_pop_value));
endmodule